package com.mrd.permissions;

import java.util.Date;

import javax.annotation.Resource;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.mrd.framework.security.config.SecurityConstants;
import com.mrd.framework.utils.HttpUtils;
import com.mrd.gtimpframe.entity.SysLog;
import com.mrd.gtimpframe.repository.SysLogMapper;
import com.mrd.redis.JedisClientClusterImpl;
import com.mrd.util.StringUtils;

/**
 * Created by zy on 2017/8/5.
 */
// todo 暂时关闭此切面，因为影响@Resource注解的使用(solve)
@Component
@Aspect
public class LogAspect {

  private final Logger LOG = LoggerFactory.getLogger(LogAspect.class);
  private final static String HAVE_EXCEPT = "1";// 有异常

  @Resource
  private SysLogMapper sysLogMapper;
  @Resource
  private FutureThreadPool futureThreadPool;
  @Resource
  private JedisClientClusterImpl redisClusterClient;

  /**
   * 定义一个切入点. 解释下：
   *
   * ~ 第一个 * 代表任意修饰符及任意返回值. ~ 第二个 * 定义在web包或者子包 ~ 第三个 * 任意方法 ~ .. 匹配任意数量的参数.
   */
  @Pointcut("execution(* com.mrd.gtimp.*.action..*.*(..)) || execution(* com.mrd.gtimpframe.action..*.*(..))")
  // @Pointcut("execution(* com.mrd.gtimp.*.action..*.*(..))")
  public void logPointcut() {}

  @Around("logPointcut()")
  public Object doAround(ProceedingJoinPoint joinPoint) {
    String account = null;
    SysLog sl = new SysLog();
    long start = System.currentTimeMillis();
    try {
      sl.setId(StringUtils.getUUID());
      sl.setFromIp(HttpUtils.getRemoteIp());
      sl.setExecMethod(joinPoint.toString());
      sl.setCtime(new Date());
      Object uobj =
          HttpUtils.getSession().getAttribute(SecurityConstants.SESSION_USER_ACCOUNT_NAME);
      account = (uobj != null) ? uobj.toString() : "";
      // System.out.println(sysLogMapper.getClass().toString());
      sl.setAccount(account);
      Object result = joinPoint.proceed();
      long end = System.currentTimeMillis();
      sl.setCostTimeMs(Long.toString(end - start));
      // sysLogMapper.insertSelective(sl);
      futureThreadPool.executeTask(new LogSubmitTask(redisClusterClient, sl));
      LOG.debug(new StringBuffer().append(account).append(" at ").append(HttpUtils.getRemoteIp())
          .append(" exec mether: ").append(joinPoint).append("\tUse time : ").append(end - start)
          .append(" ms!").toString());
      return result;
    } catch (Exception e) {
      e.printStackTrace();
      LOG.error(new StringBuffer().append("日志异步提交异常[" + e.getMessage() + "]").toString());
      long end = System.currentTimeMillis();
      LOG.error(new StringBuffer().append(account).append(" at ").append(HttpUtils.getRemoteIp())
          .append(" exec mether: ").append(joinPoint).append("\tUse time : ").append(end - start)
          .append(" ms!").toString());
      return null;
    } catch (Throwable e) {
      LOG.error(new StringBuffer().append("日志Throwable异常[" + e.getMessage() + "]").toString());
    }
    return null;
  }

}
